<script setup lang="ts" name="GoodsSku">
import { GoodsInfo, SpecItem, ValueItem } from '@/types';
import powerset from '@/utils/power-set'

const porps= defineProps<{
    goods:GoodsInfo
    skuId?:string
}>()
console.log(porps.skuId);

  const SEPARATOR = '☆'
  const emit=defineEmits<{
    (e:'changeSku',skuId:string):void
  }>()
 
  // item 是当前点击的条目所属的规格,sub是当前点击的条目
  // 当点击这个商品规格的时候做的事情有：
  //changeSelected()给当前点击的商品添加css样式，使他高亮，调用updataDisabledStatus()
  //getSelecteSpec()获取选中的规格
  //updataDisabledStatus()让没有的商品禁用，在里面用getSelecteSpec()判断当前选中的规格，用join转为字符串，禁用没有的商品
  // 1:先排除自己，然后根据商品选中的状态动态添加样式，如果选中了为true就会添加selected样式
  // 2:调用修改禁用状态的函数, 页面加载时就对所有元素进行修改
  const changeSelected=(sub:ValueItem,item:SpecItem)=>{
  // 干掉所有人
  if(sub.disabled)return
  // 干掉除了我之外的所有人
  item.values.filter(v=>v.name!==sub.name).forEach(i=>i.selected=false)
  // 修改当前被点击的对象属性 selected 取反
  // selected 默认是 undefined 而 undefined 取反正好是 true
  sub.selected=!sub.selected
  // 调用 updateDisabledStatus
  // 更新组合规格的禁用状态
  // 该调用必须在排他结束后执行
  updataDisabledStatus()

  // 获取当前选中的规格
  // 判断是否选中了所有规格, 如果选中了就子传父将 skuId 传递过去
  const result=getSelecteSpec()
  if(result.every(item=>item)){
  //得到的是数组，要把他转为字符串
  const key=result.join(SEPARATOR)
  const val=pathMap[key]
  //console.log(val[0]);得到全部选中规格的skuid
  emit('changeSku',val[0])
  }
}
//获取路径字典
  function getPathMap(){
  //1.筛选无效的数据(没有库存的)
  const skus=porps.goods.skus.filter(item=>item.inventory>0)
   // 创建一个路径字典
  const pathMap:any={}
  //筛选有库存的
  skus.forEach(item=>{
   //2.将skus转为字符串数组(都是有货的sku)
   //算法要得是字符串数组,我们要把它转为字符串数组
  const arr= item.specs.map(i=>i.valueName)
  //  console.log(arr);
  //3.调用方法生成子集
  const result=powerset(arr)
  //4.往路径字典里添加属性
  result.forEach(arritem=>{
  const key=arritem.join(SEPARATOR)
  //4.1如果对象中没有属性,就创建一个数组添加id,如果有就直接添加id
  //key in ... 判断某个属性是否在对象中
  if(key in pathMap){
  pathMap[key].push(item.id)
  }else{
  pathMap[key]=[item.id]
  }
 })
 })
 return pathMap
}
 //修改禁用状态, 页面加载时就对所有元素进行修改
  function updataDisabledStatus(){
  // 该方法的作用: 循环所有 specs(规格) 去路径字典里找, 是否存在
  // 如果存在就不禁用, 如果不存在就禁用
  porps.goods.specs.forEach((item,index)=>{
    item.values.forEach(sub=>{
      // 开发小技巧： 只要是将 if 条件表达式的结果赋值给某个对象, 都可以用这种办法: 直接将条件表达式赋给对象的属性
      const selectedArr=getSelecteSpec()
      selectedArr[index]=sub.name
      const key=selectedArr.filter(v=>v).join(SEPARATOR)
      sub.disabled=!(key in pathMap)
    })
  })
}
  //获取被选中的规格
  function getSelecteSpec(){
      // 希望获取每个规格被选中的值: ['', '', '']
  const arr:string[]=[]
  // 遍历所有的规格, 获取它们的选中状态 (selected)
  porps.goods.specs.forEach(item=>{
    const result=item.values.find(v=>v.selected)
    arr.push(result?.name||'')
  })
  return arr
}
 // 初始化勾选状态
  function initSpecSelected(){
  if(!porps.skuId)return
  console.log(11);
  
  const result=porps.goods.skus.find(item=>item.id===porps.skuId)
  console.log(result);
  
  if(!result)return
  const selectArr=result.specs.map(item=>item.valueName)
  console.log(selectArr);
  
  porps.goods.specs.forEach(item=>{
  item.values.forEach(sub=>{
    sub.selected=selectArr.includes(sub.name)
  })
 })
}
  // 1. 获取路径字典
  const pathMap=getPathMap()
  // console.log(pathMap);
  // 2. 初始化勾选状态
  initSpecSelected()
  // 3. 更新单个规格的禁用状态
  updataDisabledStatus()


</script>
<template>
  <div class="goods-sku">
    <dl v-for="item in goods.specs" :key="item.name">
      <dt>{{item.name}}</dt>
      <dd>
        <template v-for="sub in item.values" :key="sub.name">
            <img 
            v-if="sub.picture" 
            :class="{selected:sub.selected,disabled:sub.disabled}" 
            :src="sub.picture" 
            :alt="sub.name" 
            :title="sub.name"
             @click="changeSelected(sub,item)"
            />
             <span 
             :class="{selected:sub.selected,disabled:sub.disabled}"
               @click="changeSelected(sub,item)"
              v-else>{{ sub.name }}</span>
        </template>
      </dd>
    </dl>
  </div>
</template>

<style scoped lang="less">
.sku-state-mixin () {
  border: 1px solid #e4e4e4;
  margin-right: 10px;
  cursor: pointer;
  &.selected {
    border-color: @xtxColor;
  }
  &.disabled {
    opacity: 0.6;
    border-style: dashed;
    cursor: not-allowed;
  }
}
.goods-sku {
  padding-left: 10px;
  padding-top: 20px;
  dl {
    display: flex;
    padding-bottom: 20px;
    align-items: center;
    dt {
      width: 50px;
      color: #999;
    }
    dd {
      flex: 1;
      color: #666;
      > img {
        width: 50px;
        height: 50px;
        margin-top: 5px;
        .sku-state-mixin ();
      }
      > span {
        display: inline-block;
        height: 30px;
        line-height: 30px;
        padding: 0 20px;
        margin-top: 5px;
        .sku-state-mixin ();
      }
    }
  }
}
</style>
